package com.meilai.project.controller.web.report.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.meilai.project.constant.InstallTypeEnum;
import com.meilai.project.controller.web.market.mapper.BillMarketShootRequirementMapper;
import com.meilai.project.controller.web.market.vo.BillMarketShootRequirementForExportVO;
import com.meilai.project.controller.web.report.entity.WeekReportFloorOccupy;
import com.meilai.project.controller.web.report.entity.WeekReportOccupy;
import com.meilai.project.controller.web.report.mapper.WeekReportMapper;
import com.meilai.project.controller.web.report.vo.*;
import com.meilai.project.entity.business.installOrder.WorkerSubmit;
import com.meilai.project.service.business.installOrder.WorkerSubmitService;
import com.meilai.project.util.DateRange;
import com.meilai.project.util.DateRangeUtil;
import com.meilai.project.util.JavaStreamUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xchen
 * @since 2022-04-09
 */
@Slf4j
@Service
public class WeekReportServiceImpl implements WeekReportService {

    @Autowired
    private WeekReportMapper weekReportMapper;

    @Autowired
    private WorkerSubmitService workerSubmitService;

    @Autowired
    private BillMarketShootRequirementMapper billMarketShootRequirementMapper;

    @Override
    public List<WeekSummaryVO> weekSummary() {
        // 查询，行政区划、楼盘、楼层、智能框数量
        List<WeekSummaryVO> buildingList = weekReportMapper.queryBuildingBaseInfo();
        // 智能框，全部占用情况的最大时间
        LocalDate maxDate = weekReportMapper.queryMaxOccupyDate();
        // 预处理的起止日期
        LocalDate beginDate = getPublishBeginDate(); // 预处理开始日期 两周前
        LocalDate endDate = getPublishEndDate(beginDate, maxDate); // 预处理结束日期（占用最大值、半年后，中的最大值）
        // 以周六~周五为一个周期，计算所有周期时间段（预处理开始日期往前找周六，预处理结束日期往后找周五）
        List<DateRange> dateRangeList = DateRangeUtil.calcWeekRange(beginDate, endDate);
        // 所有周期的最开始日期
        LocalDate startDate = dateRangeList.get(0).getBeginDate();
        // 所有周期的最结束日期
        LocalDate endDate2 = dateRangeList.get(dateRangeList.size() - 1).getBeginDate();
        // 查询开始日期后的占用
        List<WeekReportOccupy> weekReportOccupies = weekReportMapper.querySummaryOccupy(startDate, endDate2);
        // 预锁位
        List<WeekReportOccupy> weekReportLocking = weekReportMapper.querySummaryPreLocking(startDate, endDate2);
        // 合并
        weekReportOccupies.addAll( weekReportLocking );

        // 查出开始日期后的上刊提交记录
        LocalDateTime localDateTime = beginDate.atTime(0, 0, 0, 0);
        // 销售单查询列表
        List<WorkerSubmit> list = workerSubmitService.list(Wrappers.<WorkerSubmit>lambdaQuery()
                .eq(WorkerSubmit::getInstall_type, InstallTypeEnum.PUBLISH.getInstallType())
                .eq(WorkerSubmit::getMedia_type_id, 1)
                .in(WorkerSubmit::getFlow_status, 4,3)
                .isNull(WorkerSubmit::getDeleted_at)
                .ge(WorkerSubmit::getSaved_at, localDateTime.minusMonths(1)))
                .stream().filter(JavaStreamUtil.distinctByKey(d -> d.getWork_order_id() + "_" + d.getMedia_point_id()))
                .collect(Collectors.toList());

        //移除没有出现的时间段
        for (DateRange dateRange : dateRangeList) {
            boolean hasAppear = false;
            for (WeekReportOccupy weekReportOccupy : weekReportOccupies) {
                if (weekReportOccupy.inRange(dateRange)) {
                    hasAppear = true;
                    break;
                }
            }
            if (!hasAppear) {
                dateRange.setNeed(false);
            }
        }
        // 以（楼盘id-楼层）为key，分组占用点位数据
        Map<String, List<WeekReportOccupy>> key2OccupyMap =
                weekReportOccupies.stream().collect(Collectors.groupingBy(WeekReportOccupy::weekSummaryGroupKey));

        // 总点位数
        long count = 0L;
        for (WeekSummaryVO weekSummaryVO : buildingList) {
            if (weekSummaryVO.getMedia_total_count() != null) {
                count += weekSummaryVO.getMedia_total_count();
            }
        }
        // 以（楼盘id-楼层）为key，统计时间段内的占用情况
        Map<String, Integer> map = new HashMap<>();
        for (WeekSummaryVO weekSummaryVO : buildingList) {
            // 占用点位数据
            List<WeekReportOccupy> occupyList = key2OccupyMap.getOrDefault(weekSummaryVO.groupKey(), new ArrayList<>());
            // 占用情况
            List<WeekSummaryDateRangeExt> weekSummaryDateRangeExtList = new ArrayList<>();
            weekSummaryVO.setWeekSummaryDateRangeExtList(weekSummaryDateRangeExtList);
            // 每个dateRange进行处理，不存在的则填入列表
            for (DateRange dateRange : dateRangeList) {
                WeekSummaryDateRangeExt dateRangeExt = new WeekSummaryDateRangeExt();
                dateRangeExt.setCurrentWeekOrFuture(dateRange.isCurrentWeekOrFuture());
                dateRangeExt.setTwoWeekAgo(dateRange.isTwoWeekAgo());
                dateRangeExt.setHasOccupy(dateRange.isNeed());
                dateRangeExt.setBeginDate(dateRange.getBeginDate());
                dateRangeExt.setEndDate(dateRange.getEndDate());

                // 当前周期，占用点位总数
                int totalCount = 0;

                // 在当前周期下的占用点位
                List<WeekReportOccupy> weekOccupyList = new ArrayList<>();
                for (WeekReportOccupy weekReportOccupy : occupyList) {
                    if (weekReportOccupy.inRange(dateRange)) {
                        weekOccupyList.add(weekReportOccupy);
                    }
                }

                // 在当前周期下的点位，再按照用户进行聚合
                List<WeekSummaryCustomerExt> customerOccupyInfo = new ArrayList<>(); // 占用情况-客户信息
                if (CollUtil.isNotEmpty(weekOccupyList)) {
                    //Map<Long, List<WeekReportOccupy>> customerIdMap = weekOccupyList.stream().collect(Collectors.groupingBy(WeekReportOccupy::getCustomer_id));
                    Map<String,List<WeekReportOccupy>> customerFlowMap = weekOccupyList.stream().collect(Collectors.groupingBy(WeekReportOccupy::customerGroupKey));

//                    for (Map.Entry<Long, List<WeekReportOccupy>> entity : customerIdMap.entrySet()) {
//                        List<WeekReportOccupy> customerOccupyList = entity.getValue();
//                        WeekSummaryCustomerExt ext = new WeekSummaryCustomerExt();
//                        ext.setCustomerId(entity.getKey());
//                        ext.setCustomerName(customerOccupyList.get(0).getCustomer_name());
//                        ext.setOccupyCount(customerOccupyList.size());
//                        totalCount += customerOccupyList.size();
//                        customerOccupyInfo.add(ext);
//                    }

                    for (Map.Entry<String, List<WeekReportOccupy>> entity : customerFlowMap.entrySet()) {
                        List<WeekReportOccupy> customerOccupyList = entity.getValue();
                        WeekSummaryCustomerExt ext = new WeekSummaryCustomerExt();
                        ext.setCustomerKey(entity.getKey());
                        ext.setCustomerId(customerOccupyList.get(0).getCustomer_id());
                        ext.setCustomerName(customerOccupyList.get(0).getCustomer_name());
                        ext.setOccupyCount(customerOccupyList.size());
                        ext.setFlowStatus(customerOccupyList.get(0).getFlow_status());
                        // 预锁位不占用总数
                        if(!customerOccupyList.get(0).getFlow_status().toString().equals("0")){
                            totalCount += customerOccupyList.size();
                        }
                        customerOccupyInfo.add(ext);
                    }

                }
                // 时间key
                String key = dateRange.getBeginDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + dateRange.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                Integer value = map.get(key);
                if (value == null) {
                    map.put(key, totalCount);
                } else {
                    map.put(key, value + totalCount);
                }
                dateRangeExt.setOccupyCount(totalCount);
                dateRangeExt.setCustomerOccupyInfo(customerOccupyInfo);
                LocalDateTime begin_time = dateRange.getBeginDate().atTime(0, 0, 0, 0);
                LocalDateTime end_time = dateRange.getEndDate().atTime(23, 59, 59);
                dateRangeExt.setPublish_count(list.stream().filter(item ->
                        (item.getSaved_at().isAfter(begin_time) || item.getSaved_at().equals(begin_time))
                                && (item.getSaved_at().isBefore(end_time) || item.getSaved_at().equals(end_time))).count());


                weekSummaryDateRangeExtList.add(dateRangeExt);
            }
        }
        for (WeekSummaryVO weekSummaryVO : buildingList) {
            for (WeekSummaryDateRangeExt weekSummaryDateRangeExt : weekSummaryVO.getWeekSummaryDateRangeExtList()) {
                String key = weekSummaryDateRangeExt.getBeginDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + weekSummaryDateRangeExt.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                weekSummaryDateRangeExt.setOccupy_count(map.getOrDefault(key, 0).longValue());
                weekSummaryDateRangeExt.setVacancy_count(count - weekSummaryDateRangeExt.getOccupy_count());
                weekSummaryDateRangeExt.setOccupy_percentage(new BigDecimal(weekSummaryDateRangeExt.getOccupy_count()).multiply(new BigDecimal(100)).divide(new BigDecimal(count), 2, RoundingMode.HALF_UP));
                Long publish_count = weekSummaryDateRangeExt.getPublish_count();
                if (publish_count == null) weekSummaryDateRangeExt.setPublish_count(0L);
                weekSummaryDateRangeExt.setPublish_percentage(new BigDecimal(weekSummaryDateRangeExt.getPublish_count()).multiply(new BigDecimal(100)).divide(new BigDecimal(count), 2, RoundingMode.HALF_UP));
            }
        }
        return buildingList.stream().sorted(Comparator.comparing(WeekSummaryVO::getArea_name).thenComparing(WeekSummaryVO::getBuilding_area_id)).collect(Collectors.toList());
    }

    @Override
    public List<WeekDetailVO> weekDetail(Long building_area_id) {
        //查询指定楼盘的楼栋-单元-楼层情况
        List<WeekDetailVO> result = weekReportMapper.queryBuildingFloorByBuildingId(building_area_id);
        DateRange dateRange = DateRangeUtil.calcWeekRange(LocalDate.now(), LocalDate.now()).get(0);
        //查询指定单元在本周及以后的占用情况
        List<WeekReportFloorOccupy> weekReportFloorOccupies = weekReportMapper.queryFloorOccupyByBuildingId(building_area_id, dateRange.getBeginDate(), dateRange.getEndDate().plusDays(7));
        //将在刊中和待上刊分开
        List<WeekReportFloorOccupy> inPublishList = new ArrayList<>();
        List<WeekReportFloorOccupy> waitPublishList = new ArrayList<>();
        for (WeekReportFloorOccupy weekReportFloorOccupy : weekReportFloorOccupies) {
            if (weekReportFloorOccupy.inRange(dateRange)) {
                inPublishList.add(weekReportFloorOccupy);
            } else {
                waitPublishList.add(weekReportFloorOccupy);
            }
        }
        //按楼栋-单元-楼层将在刊中和待上刊聚合
        Map<String, List<WeekReportFloorOccupy>> key2InPubOccupyMap =
                inPublishList.stream().collect(Collectors.groupingBy(WeekReportFloorOccupy::weekDetailGroupKey));
        Map<String, List<WeekReportFloorOccupy>> key2WaitPubOccupyMap =
                waitPublishList.stream().collect(Collectors.groupingBy(WeekReportFloorOccupy::weekDetailGroupKey));
        //组装每个楼层的数据
        for (WeekDetailVO detailVO : result) {
            String groupKey = detailVO.groupKey();
            //当前楼层的在刊和待上刊列表
            List<WeekReportFloorOccupy> inPublishes = key2InPubOccupyMap.get(groupKey);
            List<WeekReportFloorOccupy> waitPublishes = key2WaitPubOccupyMap.get(groupKey);
            if (null == inPublishes) {
                inPublishes = new ArrayList<>();
            }
            if (null == waitPublishes) {
                waitPublishes = new ArrayList<>();
            }
            //将当前楼层的在刊和待上刊列表按照客户进行聚合（注意，一个客户可能在一周内存在多个时间段，分开展示）
            Map<String, List<WeekReportFloorOccupy>> inPubCustomerMap = inPublishes.stream()
                    .collect(Collectors.groupingBy(WeekReportFloorOccupy::weekDetailCustomerDateRangeGroupKey));
            Map<String, List<WeekReportFloorOccupy>> waitPubCustomerMap = waitPublishes.stream()
                    .collect(Collectors.groupingBy(WeekReportFloorOccupy::weekDetailCustomerDateRangeGroupKey));
            List<WeekDetailCustomerExt> inPubRet = new ArrayList<>();
            List<WeekDetailCustomerExt> waitPubRet = new ArrayList<>();
            detailVO.setInPublish(inPubRet);
            detailVO.setWaitPublish(waitPubRet);

            //处理上刊客户列表
            processCustomerList(inPubCustomerMap, inPubRet);

            //处理待上刊客户列表
            processCustomerList(waitPubCustomerMap, waitPubRet);
            inPubRet.sort(Comparator.comparing(WeekDetailCustomerExt::getCustomerId));
            waitPubRet.sort(Comparator.comparing(WeekDetailCustomerExt::getCustomerId));
        }
        return result;
    }

    @Override
    public List<WeekDetailVO3> weekDetail2(List<Long> building_area_ids) {
        List<WeekDetailVO3> result = new ArrayList<>();
        //查询指定楼盘的楼栋-单元-楼层情况
        List<WeekDetailVO2> weekDetailVO2List = weekReportMapper.queryBuildingFloorByBuildingIds(building_area_ids);
        DateRange dateRange = DateRangeUtil.calcWeekRange(LocalDate.now(), LocalDate.now()).get(0);

        //查询指定单元在本周及以后的占用情况
        List<WeekReportFloorOccupy2> weekReportFloorOccupies = weekReportMapper.queryFloorOccupyByBuildingIds(building_area_ids, dateRange.getBeginDate(), dateRange.getEndDate().plusDays(7));

        // 所有相关的市场单ids
        Set<Long> billMarketIds = weekReportFloorOccupies.stream().map(WeekReportFloorOccupy2::getBill_market_id).collect(Collectors.toSet());
        // 所有拍照要求
        List<BillMarketShootRequirementForExportVO> shootReqList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(billMarketIds)) shootReqList = billMarketShootRequirementMapper.getShootRequirementsByMarketIds(billMarketIds);
        // <市场单id，拍照要求> 上刊
        Map<Long, List<BillMarketShootRequirementForExportVO>> toPubShootReqMap = shootReqList.stream()
                .filter(d -> d.getShoot_type()==1 && (d.getMedia_type_id() == -1 ||d.getMedia_type_id() == 1))
                .collect(Collectors.groupingBy(BillMarketShootRequirementForExportVO::getBill_market_id));
        // <市场单id，拍照要求> 下刊
        Map<Long, List<BillMarketShootRequirementForExportVO>> unPubShootReqMap = shootReqList.stream()
                .filter(d -> d.getShoot_type()==2 && (d.getMedia_type_id() == -1 ||d.getMedia_type_id() == 1))
                .collect(Collectors.groupingBy(BillMarketShootRequirementForExportVO::getBill_market_id));

        Map<String, List<WeekDetailVO2>> buildingMap = weekDetailVO2List.stream().collect(Collectors.groupingBy(WeekDetailVO2::getBuilding_id));
        Map<String, List<WeekReportFloorOccupy2>> occupyMap = weekReportFloorOccupies.stream().collect(Collectors.groupingBy(WeekReportFloorOccupy2::getBuilding_id));
        for (Map.Entry<String, List<WeekDetailVO2>> entry : buildingMap.entrySet()) {
            List<WeekDetailVO2> vo2List = entry.getValue();
            List<WeekReportFloorOccupy2> occupyList = occupyMap.getOrDefault(entry.getKey(), new ArrayList<>());

            WeekDetailVO3 oneBuilding = new WeekDetailVO3();
            result.add(oneBuilding);
            oneBuilding.setBuilding_id(entry.getKey());
            oneBuilding.setWeekDetailVO2List(vo2List);

            // <客户id，客户名称>
            Map<Long, String> customerMap = occupyList.stream()
                    .collect(Collectors.toMap(WeekReportFloorOccupy2::getCustomer_id, WeekReportFloorOccupy2::getCustomer_name, (k1, k2) -> k2));
            // <客户id，市场单id> 上刊
            Map<Long, Set<Long>> inPubCustomerMarketIds = new HashMap<>();
            // <客户id，点位数量> 上刊
            Map<Long, Integer> inPubCustomerOccupy = new HashMap<>();
            // <客户id，市场单id> 待上刊
            Map<Long, Set<Long>> waitPubCustomerMarketIds = new HashMap<>();
            // <客户id，点位数量> 待上刊
            Map<Long, Integer> waitPubCustomerOccupy = new HashMap<>();

            //将在刊中和待上刊分开
            List<WeekReportFloorOccupy2> inPublishList = new ArrayList<>();
            List<WeekReportFloorOccupy2> waitPublishList = new ArrayList<>();
            for (WeekReportFloorOccupy2 weekReportFloorOccupy : occupyList) {
                if (weekReportFloorOccupy.inRange(dateRange)) {
                    inPublishList.add(weekReportFloorOccupy);
                } else {
                    waitPublishList.add(weekReportFloorOccupy);
                }
            }
            //按楼栋-单元-楼层将在刊中和待上刊聚合
            Map<String, List<WeekReportFloorOccupy2>> key2InPubOccupyMap =
                    inPublishList.stream().collect(Collectors.groupingBy(WeekReportFloorOccupy2::weekDetailGroupKey));
            Map<String, List<WeekReportFloorOccupy2>> key2WaitPubOccupyMap =
                    waitPublishList.stream().collect(Collectors.groupingBy(WeekReportFloorOccupy2::weekDetailGroupKey));
            //组装每个楼层的数据
            for (WeekDetailVO2 detailVO : vo2List) {
                String groupKey = detailVO.groupKey();
                //当前楼层的在刊和待上刊列表
                List<WeekReportFloorOccupy2> inPublishes = key2InPubOccupyMap.get(groupKey);
                List<WeekReportFloorOccupy2> waitPublishes = key2WaitPubOccupyMap.get(groupKey);
                if (null == inPublishes) {
                    inPublishes = new ArrayList<>();
                }
                if (null == waitPublishes) {
                    waitPublishes = new ArrayList<>();
                }
                //将当前楼层的在刊和待上刊列表按照客户进行聚合（注意，一个客户可能在一周内存在多个时间段，分开展示）
                Map<String, List<WeekReportFloorOccupy2>> inPubCustomerMap = inPublishes.stream()
                        .collect(Collectors.groupingBy(WeekReportFloorOccupy2::weekDetailCustomerDateRangeGroupKey));
                Map<String, List<WeekReportFloorOccupy2>> waitPubCustomerMap = waitPublishes.stream()
                        .collect(Collectors.groupingBy(WeekReportFloorOccupy2::weekDetailCustomerDateRangeGroupKey));
                List<WeekDetailCustomerExt2> inPubRet = new ArrayList<>();
                List<WeekDetailCustomerExt2> waitPubRet = new ArrayList<>();
                detailVO.setInPublish(inPubRet);
                detailVO.setWaitPublish(waitPubRet);

                //处理上刊客户列表
                processCustomerList2(inPubCustomerMap, inPubRet, inPubCustomerMarketIds, inPubCustomerOccupy);

                //处理待上刊客户列表
                processCustomerList2(waitPubCustomerMap, waitPubRet, waitPubCustomerMarketIds, waitPubCustomerOccupy);
                inPubRet.sort(Comparator.comparing(WeekDetailCustomerExt2::getCustomerId));
                waitPubRet.sort(Comparator.comparing(WeekDetailCustomerExt2::getCustomerId));
            }

            // 需要下刊的幅数
            int toUnPublishCount = inPubCustomerOccupy.values().stream().reduce(0, Integer::sum);
            // 需要上刊的幅数
            int toInPublishCount = waitPubCustomerOccupy.values().stream().reduce(0, Integer::sum);
            // 总幅数
            oneBuilding.setPointCount(toUnPublishCount + toInPublishCount);

            // 拍照要求
            // 需要下刊的
            oneBuilding.setToUnPublishShootRequirements(inPubCustomerMarketIds.entrySet().stream().map(d -> {
                Long customerId = d.getKey();
                StringBuilder sb = new StringBuilder("");
                sb.append(customerMap.getOrDefault(customerId, "")); // 客户名称
                sb.append(inPubCustomerOccupy.getOrDefault(customerId, 0)).append("幅，拍照要求：");
                boolean hasShoot = false;
                for (Map.Entry<Long, List<BillMarketShootRequirementForExportVO>> shootEntry : unPubShootReqMap.entrySet()) {
                    if(d.getValue().contains(shootEntry.getKey())){
                        for (BillMarketShootRequirementForExportVO requirement : shootEntry.getValue()) {
                            hasShoot = true;
                            sb.append(requirement.description()).append("\r\n");
                        }
                    }
                }
                if(!hasShoot) sb.append("无\r\n");
                return sb.toString();
            }).collect(Collectors.toList()));
            // 需要上刊的
            oneBuilding.setToInPublishShootRequirements(waitPubCustomerMarketIds.entrySet().stream().map(d -> {
                Long customerId = d.getKey();
                StringBuilder sb = new StringBuilder("");
                sb.append(customerMap.getOrDefault(customerId, "")); // 客户名称
                sb.append(waitPubCustomerOccupy.getOrDefault(customerId, 0)).append("幅，拍照要求：");
                boolean hasShoot = false;
                for (Map.Entry<Long, List<BillMarketShootRequirementForExportVO>> shootEntry : toPubShootReqMap.entrySet()) {
                    if(d.getValue().contains(shootEntry.getKey())){
                        for (BillMarketShootRequirementForExportVO requirement : shootEntry.getValue()) {
                            hasShoot = true;
                            sb.append(requirement.description()).append("\r\n");
                        }
                    }
                }
                if(!hasShoot) sb.append("无\r\n");
                return sb.toString();
            }).collect(Collectors.toList()));
        }

        return result;
    }

    private void processCustomerList(Map<String, List<WeekReportFloorOccupy>> pubCustomerMap, List<WeekDetailCustomerExt> pubRet) {
        for (Map.Entry<String, List<WeekReportFloorOccupy>> entry : pubCustomerMap.entrySet()) {
            List<WeekReportFloorOccupy> occupyPoints = entry.getValue();
            WeekReportFloorOccupy weekReportFloorOccupy = occupyPoints.get(0);
            WeekDetailCustomerExt weekDetailCustomerExt = new WeekDetailCustomerExt();
            weekDetailCustomerExt.setCustomerId(weekReportFloorOccupy.getCustomer_id());
            weekDetailCustomerExt.setCustomerName(weekReportFloorOccupy.getCustomer_name());
            weekDetailCustomerExt.setBeginDate(weekReportFloorOccupy.getStart_at());
            weekDetailCustomerExt.setEndDate(weekReportFloorOccupy.getEnd_at());
            weekDetailCustomerExt.setOccupyCount(occupyPoints.size());
            pubRet.add(weekDetailCustomerExt);
        }
    }

    private void processCustomerList2(Map<String, List<WeekReportFloorOccupy2>> pubCustomerMap,
                                      List<WeekDetailCustomerExt2> pubRet,
                                      Map<Long, Set<Long>> customerMarketIds,
                                      Map<Long, Integer> customerOccupy) {
        for (Map.Entry<String, List<WeekReportFloorOccupy2>> entry : pubCustomerMap.entrySet()) {
            List<WeekReportFloorOccupy2> occupyPoints = entry.getValue();
            WeekReportFloorOccupy2 weekReportFloorOccupy = occupyPoints.get(0);
            WeekDetailCustomerExt2 weekDetailCustomerExt = new WeekDetailCustomerExt2();
            weekDetailCustomerExt.setCustomerId(weekReportFloorOccupy.getCustomer_id());
            weekDetailCustomerExt.setCustomerName(weekReportFloorOccupy.getCustomer_name());
            weekDetailCustomerExt.setBeginDate(weekReportFloorOccupy.getStart_at());
            weekDetailCustomerExt.setBeginDateStr(weekReportFloorOccupy.getStart_at_str());
            weekDetailCustomerExt.setEndDate(weekReportFloorOccupy.getEnd_at());
            weekDetailCustomerExt.setEndDateStr(weekReportFloorOccupy.getEnd_at_str());
            weekDetailCustomerExt.setOccupyCount(occupyPoints.size());
            pubRet.add(weekDetailCustomerExt);

            Set<Long> marketIds = customerMarketIds.getOrDefault(weekReportFloorOccupy.getCustomer_id(), new HashSet<>());
            marketIds.add(weekReportFloorOccupy.getBill_market_id());
            customerMarketIds.put(weekReportFloorOccupy.getCustomer_id(), marketIds);

            Integer occupySum = customerOccupy.getOrDefault(weekReportFloorOccupy.getCustomer_id(), 0);
            customerOccupy.put(weekReportFloorOccupy.getCustomer_id(), occupySum + occupyPoints.size());
        }
    }

    private DateRange getInPublishDateRange() {
        LocalDate beginDate = getPublishBeginDate();
        List<DateRange> dateRanges = DateRangeUtil.calcWeekRange(beginDate, beginDate);
        return dateRanges.get(0);
    }

    private LocalDate getPublishBeginDate() {
        return LocalDate.now().minusWeeks(2);
    }

    private LocalDate getPublishEndDate(LocalDate beginDate, LocalDate maxDate) {
        LocalDate halfYear = beginDate.plusMonths(6);
        if (null == maxDate || halfYear.isAfter(maxDate)) {
            return halfYear;
        }
        return maxDate;
    }

}
